﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeresyManager.Comunication;

namespace HeresyManager.Careers
{
    [Serializable]
    public class Adept : Career
    {

        private Skill[] skills;
        private Talent[] talents;

        public override string Name
        {
            get { return "Adept"; }
        }

        public override IEnumerator<Comunicator> Acire(Character c)
        {

            List<Skill> skillList = new List<Skill>();

            skillList.Add(new Skills.SpeakLanguages.SpeakLanguageLowGothic(Skill.SkillLevel.Skilled));
            skillList.Add(new Skills.Literacy(Skill.SkillLevel.Skilled));

            var skillChosser = new Comunication.ChooseOne<Skill>("Select One", new Skills.Trades.TradeCopyist(Skill.SkillLevel.Skilled), new Skills.Trades.TradeValet(Skill.SkillLevel.Skilled));
            while (skillChosser.SelectedValue == null)
                yield return skillChosser;
            skillList.Add(skillChosser.SelectedValue);

            skillList.Add(new Skills.CommonLores.CommonLoreImperium(Skill.SkillLevel.Skilled));

            skillChosser = new Comunication.ChooseOne<Skill>("Select One", new Skills.ScholasticLores.ScholasticLoreLegend(Skill.SkillLevel.Skilled), new Skills.CommonLores.CommonLoreTech(Skill.SkillLevel.Skilled));
            while (skillChosser.SelectedValue == null)
                yield return skillChosser;
            skillList.Add(skillChosser.SelectedValue);

            skills = skillList.ToArray();

            foreach (var s in skills)
            {
                var en = c.AddSkill(s, this);
                while (en.MoveNext())
                    yield return en.Current;
            }




            List<Talent> talentList = new List<Talent>();

            var choose = new ChooseOne<Talent>("Choose One", new Talents.WeaponTraining.MeleeWeaponTrainingPrimitive(), new Talents.WeaponTraining.PistolTrainingSP());
            while (choose.SelectedValue == null)
                yield return choose;
            talentList.Add(choose.SelectedValue);

            choose = new ChooseOne<Talent>("Choose One", new Talents.Resistances.ResistanceCold(), new Talents.LightSleeper());
            while (choose.SelectedValue == null)
                yield return choose;
            talentList.Add(choose.SelectedValue);


            choose = new ChooseOne<Talent>("Choose One", new Talents.Sprint(), new Talents.Unremarkable());
            while (choose.SelectedValue == null)
                yield return choose;
            talentList.Add(choose.SelectedValue);


            talents = talentList.ToArray();

            foreach (var s in talents)
            {
                var en = c.AddTalent(s, this);
                while (en.MoveNext())
                    yield return en.Current;
            }

        }

        public override void DeAcire(Character c)
        {
            foreach (var s in skills)
            {
                c.RemoveSkill(s, this);
            }

            foreach (var item in talents)
            {
                c.RemoveTalent(item, this);
            }
            this.talents = null;
        }

        public override Rank[] Ranks
        {
            get { return new Rank[] { new Archivist(), new Scrivener(), new Scribe(), new Inditor(), new Chirurgeon(), new Scholar(), new Lexographer(), new Loremaster(), new Comptroller(), new Logister(), new Magister(), new Sage() }; }
        }

        public override BackgroundPackage[] BackgroundPackages
        {
            get { return new BackgroundPackage[] { new MunitorumQuastor(), new ScholarOfTheCollegesHetaireiaLexis(), new VoidCommercia() }; }
        }

        #region BackgroundPackages

        [Serializable]
        private class MunitorumQuastor : BackgroundPackage
        {

            private Skill[] skills;

            private Talent talent;


            public override string Name
            {
                get { return "Munitorum Quastor"; }
            }

            public override int Cost
            {
                get { return 100; }
            }


            public override IEnumerator<Comunicator> Accire(Character c)
            {
                var en = base.Accire(c);
                while (en.MoveNext())
                    yield return en.Current;

                c.Fel -= 5;
                c.Wp -= 5;

                talent = new Talents.Paranoia();

                en = c.AddTalent(talent, this);
                while (en.MoveNext())
                    yield return en.Current;

                skills = new Skill[] { new Skills.Command(Skill.SkillLevel.Skilled), new Skills.CommonLores.CommonLoreImperialGuard(Skill.SkillLevel.Skilled), new Skills.Inquiry(Skill.SkillLevel.Skilled), new Skills.Search(Skill.SkillLevel.Skilled), new Skills.Security(Skill.SkillLevel.Skilled) };
                foreach (var s in skills)
                {
                    en = c.AddSkill(s, this);
                    while (en.MoveNext())
                        yield return en.Current;
                }



            }

            public override void DeAccire(Character c)
            {
                base.DeAccire(c);
                c.RemoveTalent(talent, this);
                foreach (var s in skills)
                {
                    c.RemoveSkill(s, this);
                }
                c.Fel += 5;
                c.Wp += 5;
            }
        }
        [Serializable]
        private class ScholarOfTheCollegesHetaireiaLexis : BackgroundPackage
        {

            private Skill[] skills;

            private Talent talent;


            public override string Name
            {
                get { return "Scholar Of The Colleges Hetaireia Lexis"; }
            }

            public override int Cost
            {
                get { return 100; }
            }

            public override bool IsPreconditionSattisfied(Character c)
            {
                return base.IsPreconditionSattisfied(c) && c.HomeWorld is HomeWorlds.ImperialWorld || c.HomeWorld is HomeWorlds.NobleBorn;
            }

            public override IEnumerator<Comunicator> Accire(Character c)
            {
                var en = base.Accire(c);
                while (en.MoveNext())
                    yield return en.Current;

                c.Int += 3;
                c.S -= 5;
                c.WS -= 5;

                talent = new Talents.Peers.PeerAcademics();

                en = c.AddTalent(talent, this);
                while (en.MoveNext())
                    yield return en.Current;

                var skillList = new List<Skill>();

                skillList.Add(new Skills.Cipherses.CiphersSecretSociety(Skill.SkillLevel.Skilled));

                var com = new Comunication.ChoseSkilFromType("Choose One", c, typeof(Skills.ForbiddenLore), Skill.SkillLevel.Skilled);
                while (com.SelectedValue == null)
                    yield return com;
                skillList.Add(com.SelectedValue);

                com = new Comunication.ChoseSkilFromType("Choose One", c, typeof(Skills.ScholasticLore), Skill.SkillLevel.Skilled);
                while (com.SelectedValue == null)
                    yield return com;
                skillList.Add(com.SelectedValue);

                skills = skillList.ToArray();
                foreach (var s in skills)
                {
                    en = c.AddSkill(s, this);
                    while (en.MoveNext())
                        yield return en.Current;
                }



            }

            public override void DeAccire(Character c)
            {
                base.DeAccire(c);
                c.RemoveTalent(talent, this);
                foreach (var s in skills)
                {
                    c.RemoveSkill(s, this);
                }
                c.Int -= 3;
                c.S += 5;
                c.WS += 5;
            }
        }
        [Serializable]
        private class VoidCommercia : BackgroundPackage
        {

            private Skill[] skills;

            private Talent talent;


            public override string Name
            {
                get { return "Void Commercia"; }
            }

            public override int Cost
            {
                get { return 200; }
            }

            public override bool IsPreconditionSattisfied(Character c)
            {
                return base.IsPreconditionSattisfied(c) && c.HomeWorld is HomeWorlds.VoidBorn;
            }

            public override IEnumerator<Comunicator> Accire(Character c)
            {
                var en = base.Accire(c);
                while (en.MoveNext())
                    yield return en.Current;

                c.T -= 5;
                c.WS -= 5;

                talent = new Talents.Peers.PeerAcademics();

                en = c.AddTalent(talent, this);
                while (en.MoveNext())
                    yield return en.Current;



                skills = new Skill[] { new Skills.Barter(Skill.SkillLevel.Skilled), new Skills.Charm(Skill.SkillLevel.Skilled), new Skills.CommonLores.CommonLoreImperium(Skill.SkillLevel.Skilled), new Skills.CommonLores.CommonLoreAdeptusMercantile(Skill.SkillLevel.Skilled), new Skills.Evaluate(Skill.SkillLevel.Skilled), new Skills.Scrutiny(Skill.SkillLevel.Skilled) };
                foreach (var s in skills)
                {
                    en = c.AddSkill(s, this);
                    while (en.MoveNext())
                        yield return en.Current;
                }



            }

            public override void DeAccire(Character c)
            {
                base.DeAccire(c);
                c.RemoveTalent(talent, this);
                foreach (var s in skills)
                {
                    c.RemoveSkill(s, this);
                }

                c.T += 5;
                c.WS += 5;
            }
        }
        #endregion

        #region Ranks

        [Serializable]
        private class Archivist : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Drives.DriveGroundVehicle(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Drives.DriveHover(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Pilots.PilotCivilianCraft(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreLegend(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Trades.TradeCook(Skill.SkillLevel.Skilled)),
                new TalentBuyable(new Talents.Resistances.ResistanceCold()),
                new TalentBuyable(new Talents.SoundConstitution()),
                new TalentBuyable(new Talents.Sprint()),
                new TalentBuyable(new Talents.Unremarkable()),
                new SkillBuyable(new Skills.Swim(Skill.SkillLevel.Skilled),200),
                new TalentBuyable(new Talents.WeaponTraining.MeleeWeaponTrainingPrimitive(),200),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingPrimitive(),200),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingLas(),200),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingSP(),200),
                new TalentBuyable(new Talents.WeaponTraining.ThrownWeaponTrainingPrimitive(),200)
            };


            public override int MinimumExp
            {
                get { return 0; }
            }

            public override string Name
            {
                get { return "Archivist"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Scrivener : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Awareness(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreAdministratum(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreImperium(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Drives.DriveGroundVehicle(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Drives.DriveHover(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreCults(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Inquiry(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Literacy(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Logic(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Pilots.PilotCivilianCraft(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreLegend(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.SpeakLanguages.SpeakLanguageHighGothic(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Trades.TradeArtist(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Trades.TradeCartographer(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Trades.TradeCopyist(Skill.SkillLevel.Skilled)),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingPrimitive()),
                new TalentBuyable(new Talents.Peers.PeerAcademics()),
                new SkillBuyable(new Skills.Blather(Skill.SkillLevel.Skilled),200),
                new TalentBuyable(new Talents.Peers.PeerAdministratum(),200),
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Archivist);
            }

            public override int MinimumExp
            {
                get { return 500; }
            }

            public override string Name
            {
                get { return "Scrivener"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Scribe : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Awareness(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreAdministratum(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreEcclesiarchy(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreImperium(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreTech(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Drives.DriveGroundVehicle(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Drives.DriveHover(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreCults(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreHeresy(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Literacy(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Pilots.PilotCivilianCraft(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreBureaucracy(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreLegend(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreOccult(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.SecretTongues.SecretTongueAdministratum(Skill.SkillLevel.Skilled)),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingLas()),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingSP()),
                new TalentBuyable(new Talents.Flagellant()),
                new TalentBuyable(new Talents.Resistances.ResistancePoisons()),
                new SkillBuyable(new Skills.Blather(Skill.SkillLevel.Advanced),200),
                new TalentBuyable(new Talents.ElectroGraftUse(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new TalentBuyable(new Talents.Ambidextrous(),300),
            };


            public override int MinimumExp
            {
                get { return 1000; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Scrivener);
            }

            public override string Name
            {
                get { return "Scribe"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Inditor : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Awareness(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreTech(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreMachineCult(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Evaluate(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreMutants(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreInquisition(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Inquiry(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Logic(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreChymistry(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreNumerology(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreOccult(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.SecretTongues.SecretTongueAdministratum(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.TechUse(Skill.SkillLevel.Skilled)),
                new TalentBuyable(new Talents.TotalRecall()),
                new TalentBuyable(new Talents.SwiftAttack()),
                new SkillBuyable(new Skills.Barter(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Blather(Skill.SkillLevel.Master),200),
                new SkillBuyable(new Skills.Navigations.NavigationStellar(Skill.SkillLevel.Skilled),200),
                new TalentBuyable(new Talents.WeaponTraining.MeleeWeaponTrainingShock(),200),
                new TalentBuyable(new Talents.ArmsMaster(),200),
                new TalentBuyable(new Talents.Marksman(),300),
            };


            public override int MinimumExp
            {
                get { return 2000; }
            }

            public override string Name
            {
                get { return "Inditor"; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && !c.Ranks.Any(t => t is Chirurgeon) && c.Ranks.Any(t => t is Scribe);
            }


            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Chirurgeon : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Awareness(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreImperialCreed(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Deceive(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreMutants(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreInquisition(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Inquiry(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Medicae(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Medicae(Skill.SkillLevel.Advanced)),
                new TalentBuyable(new Talents.MasterChirugeon()),
                new TalentBuyable(new Talents.Talented(new Skills.Blather(Skill.SkillLevel.Skilled))),
                new TalentBuyable(new Talents.Talented(new Skills.Medicae(Skill.SkillLevel.Skilled))),
                new TalentBuyable(new Talents.Peers.PeerTheInsane()),
                new SkillBuyable(new Skills.Carouse(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Carouse(Skill.SkillLevel.Advanced),200),
                new TalentBuyable(new Talents.Decadence(),200),
                new TalentBuyable(new Talents.HeightenedSenseses.HeightenedSensesSight(),200),
                new TalentBuyable(new Talents.HeightenedSenseses.HeightenedSensesSmell(),200),
                new TalentBuyable(new Talents.HeightenedSenseses.HeightenedSensesTouch(),200),
                new TalentBuyable(new Talents.WeaponTraining.MeleeWeaponTrainingChain(),200),
                new SkillBuyable(new Skills.Charm(Skill.SkillLevel.Skilled),300),
                new SkillBuyable(new Skills.SlightOfHand(Skill.SkillLevel.Skilled),300),
                
            };


            public override int MinimumExp
            {
                get { return 2000; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && !c.Ranks.Any(t => t is Inditor) && c.Ranks.Any(t => t is Scribe);
            }


            public override string Name
            {
                get { return "Chirurgeon"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }


        [Serializable]
        private class Scholar : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.CommonLores.CommonLoreAdeptusArbites(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreAdministratum(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreEcclesiarchy(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreTech(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Deceive(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Dodge(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Drives.DriveWalker(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreHeresy(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreInquisition(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreMutants(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreAstromancy(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreBureaucracy(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreHeraldry(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreImperialCreed(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Scrutiny(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.SpeakLanguages.SpeakLanguageHighGothic(Skill.SkillLevel.Advanced)),
                new TalentBuyable(new Talents.ArmourOfContempt()),
                new TalentBuyable(new Talents.BinaryChatter()),
                new SkillBuyable(new Skills.Navigations.NavigationStellar(Skill.SkillLevel.Advanced),200),
                new TalentBuyable(new Talents.WeaponTraining.BasicWeaponTrainingBolt(),200),
                new TalentBuyable(new Talents.DieHard(),200),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingBolt(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new TalentBuyable(new Talents.StepASide(),200),
                
            };

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && (c.Ranks.Any(t => t is Chirurgeon) || c.Ranks.Any(t => t is Inditor));
            }


            public override int MinimumExp
            {
                get { return 3000; }
            }

            public override string Name
            {
                get { return "Scholar"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Lexographer : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreCults(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreHeresy(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreInquisition(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreMutants(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.SpeakLanguages.SpeakLanguageHighGothic(Skill.SkillLevel.Master)),
                new TalentBuyable(new Talents.Resistances.ResistanceFear()),
                new TalentBuyable(new Talents.Paranoia()),
                new TalentBuyable(new Talents.BlindFighting(),200),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingFlame(),200),
                new TalentBuyable(new Talents.QuickDraw(),200),
                new SkillBuyable(new Skills.LipReading(Skill.SkillLevel.Skilled),300),
                
            };


            public override int MinimumExp
            {
                get { return 6000; }
            }

            public override string Name
            {
                get { return "Lexographer"; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && !c.Ranks.Any(t => t is Comptroller) && c.Ranks.Any(t => t is Scholar);
            }


            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Loremaster : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreOccult(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.LipReading(Skill.SkillLevel.Advanced),200),
                new TalentBuyable(new Talents.MinorPsychicPower(),200),
                new TalentBuyable(new Talents.MinorPsychicPower(),200),
                new TalentBuyable(new Talents.MinorPsychicPower(),200),
                new TalentBuyable(new Talents.Peers.PeerAstropaths(),200),
                new TalentBuyable(new Talents.RapidReload(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),
                new SkillBuyable(new Skills.Psyniscience(Skill.SkillLevel.Skilled),300),
                new TalentBuyable(new Talents.ExoticWeaponTraining("Needle Pistol"),300),
                new TalentBuyable(new Talents.PsyRating1(),300),
                new TalentBuyable(new Talents.UnshakeabkleFaith(),300),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingPlasma(),400),
            };


            public override int MinimumExp
            {
                get { return 8000; }
            }

            public override string Name
            {
                get { return "Loremaster Lexographer"; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Lexographer);
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Comptroller : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.Command(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreMachineCult(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreMachineCult(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Deceive(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Evaluate(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Evaluate(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Inquiry(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreAstromancy(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreBureaucracy(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreChymistry(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreChymistry(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreCryptology(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreHeraldry(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreImperialCreed(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreJudgement(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreNumerology(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreNumerology(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreTacticaImperialis(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.Search(Skill.SkillLevel.Skilled)),
                new SkillBuyable(new Skills.SecretTongues.SecretTongueAdministratum(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.SecretTongues.SecretTongueAdministratum(Skill.SkillLevel.Master)),

                new TalentBuyable(new Talents.ChemGeld()),
                new TalentBuyable(new Talents.DisturbingVoice()),
                new TalentBuyable(new Talents.Resistances.ResistancePsychicPowers()),

                new SkillBuyable(new Skills.Interrogation(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.TechUse(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.TechUse(Skill.SkillLevel.Advanced),200),

                new TalentBuyable(new Talents.BlindFighting(),200),
                new TalentBuyable(new Talents.DeadeyeShot(),200),
                new TalentBuyable(new Talents.Jaded(),300),

            };


            public override int MinimumExp
            {
                get { return 6000; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && !c.Ranks.Any(t => t is Lexographer) && c.Ranks.Any(t => t is Scholar);
            }

            public override string Name
            {
                get { return "Comptroller"; }
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Logister : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.CommonLores.CommonLoreAdeptusArbites(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.CommonLores.CommonLoreEcclesiarchy(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.Logic(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Logic(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreCryptology(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreImperialCreed(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreJudgement(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreTacticaImperialis(Skill.SkillLevel.Advanced)),
                new SkillBuyable(new Skills.Search(Skill.SkillLevel.Advanced)),

                new TalentBuyable(new Talents.AirOfAuthority()),
                new TalentBuyable(new Talents.Orthoproxy()),
                new TalentBuyable(new Talents.Peers.PeerGovernment()),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingFlame()),
                new TalentBuyable(new Talents.Resistances.ResistanceFear()),
                new TalentBuyable(new Talents.StrongMinded()),
                new TalentBuyable(new Talents.Talented(new Skills.Logic(Skill.SkillLevel.Skilled))),

                new SkillBuyable(new Skills.Command(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.Interrogation(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.TechUse(Skill.SkillLevel.Master),200),

                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreArcheotech(Skill.SkillLevel.Skilled),300),

                new TalentBuyable(new Talents.NervesOfSteel(),300),
                new TalentBuyable(new Talents.Peers.PeerAdeptusMechanicus(),300),
                new TalentBuyable(new Talents.Peers.PeerEcclesiarchy(),300),
                new TalentBuyable(new Talents.SoundConstitution(),300),

            };


            public override int MinimumExp
            {
                get { return 8000; }
            }

            public override string Name
            {
                get { return "Logister Comptroller"; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Comptroller);
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }

        [Serializable]
        private class Magister : Rank
        {
            private Buyable[] b = new Buyable[] {
                new TalentBuyable(new Talents.Catfall()),

                new SkillBuyable(new Skills.Interrogation(Skill.SkillLevel.Skilled),200),
                new SkillBuyable(new Skills.Psyniscience(Skill.SkillLevel.Advanced),200),
                new SkillBuyable(new Skills.TechUse(Skill.SkillLevel.Advanced),200),

                new TalentBuyable(new Talents.ExoticWeaponTraining("Needle Rifle"),200),
                new TalentBuyable(new Talents.MinorPsychicPower(),200),
                new TalentBuyable(new Talents.MinorPsychicPower(),200),
                new TalentBuyable(new Talents.MinorPsychicPower(),200),
                new TalentBuyable(new Talents.SoundConstitution(),200),

                new TalentBuyable(new Talents.PsyRating2(),300),

                new TalentBuyable(new Talents.WeaponTraining.MeleeWeaponTrainingPower(),400),
                new TalentBuyable(new Talents.WeaponTraining.PistolTrainingMelta(),400),

                new TalentBuyable(new Talents.PsyRating3(),500),

            };


            public override int MinimumExp
            {
                get { return 10000; }
            }

            public override string Name
            {
                get { return "Loremaster Magister"; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Loremaster);
            }

            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }


        [Serializable]
        private class Sage : Rank
        {
            private Buyable[] b = new Buyable[] {
                new SkillBuyable(new Skills.CommonLores.CommonLoreAdeptusArbites(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreCults(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreHeresy(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreInquisition(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreMutants(Skill.SkillLevel.Master)),
                new SkillBuyable(new Skills.ScholasticLores.ScholasticLoreTacticaImperialis(Skill.SkillLevel.Master)),

                new TalentBuyable(new Talents.MentalFortress()),
                new TalentBuyable(new Talents.Peers.PeerNobility()),

                new SkillBuyable(new Skills.Command(Skill.SkillLevel.Master),200),

                new TalentBuyable(new Talents.ExoticWeaponTraining("Web Pistol"),200),
                new TalentBuyable(new Talents.QuickDraw(),200),
                new TalentBuyable(new Talents.RapidReload(),200),
                new TalentBuyable(new Talents.Talented(new Skills.Command(Skill.SkillLevel.Skilled)),200),

                new SkillBuyable(new Skills.Concealment(Skill.SkillLevel.Skilled),300),
                new SkillBuyable(new Skills.ForbiddenLores.ForbiddenLoreArcheotech(Skill.SkillLevel.Advanced),300),

                new TalentBuyable(new Talents.Peers.PeerAdeptusArbites(),300),
                new TalentBuyable(new Talents.SoundConstitution(),300),
                
                new TraitBuyable(new Traits.UnnaturalCharacteristic( Charackteristic.Intelligence),500),

            };


            public override int MinimumExp
            {
                get { return 10000; }
            }

            public override string Name
            {
                get { return "Sage Logister"; }
            }

            public override bool IsPreconditionSatisfied(Character c)
            {
                return base.IsPreconditionSatisfied(c) && c.Ranks.Any(t => t is Logister);
            }


            public override Rank.Buyable[] Buyables
            {
                get { return b; }
            }
        }


        #endregion

        public override int[] WeaponSkillCost
        {
            get { return new int[] { 500, 750, 1000, 2500 }; }
        }

        public override int[] BalisticSkillCost
        {
            get { return new int[] { 250, 500, 750, 1000 }; }
        }

        public override int[] StrengthCost
        {
            get { return new int[] { 500, 750, 1000, 2500 }; }
        }

        public override int[] ToughnessCost
        {
            get { return new int[] { 500, 750, 1000, 2500 }; }
        }

        public override int[] AgilityCost
        {
            get { return new int[] { 250, 500, 750, 1000 }; }
        }

        public override int[] IntelligenceCost
        {
            get { return new int[] { 100, 250, 500, 500 }; }
        }

        public override int[] PerceptionCost
        {
            get { return new int[] { 100, 250, 500, 750 }; }
        }

        public override int[] WillpowerCost
        {
            get { return new int[] { 100, 250, 500, 750 }; }
        }

        public override int[] FellowshipCost
        {
            get { return new int[] { 250, 500, 750, 1000 }; }
        }
    }
}
